using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
namespace Fcdbas.Core
{
	[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
	[System.Serializable]
	public class SalArray : System.Collections.IList, System.Collections.ICollection, System.Collections.IEnumerable
	{
		internal class Enumerator : System.Collections.IEnumerator
		{
			private System.Array m_array;
			private object m_null;
			private object m_current;
			private int m_dimensions;
			private bool m_complete;
			private int[] m_indices;
			private int[] m_lengths;
			private int[] m_lowerBounds;
			public object Current
			{
				get
				{
					return this.m_current;
				}
			}
			public Enumerator(SalArray array)
			{
				this.m_null = array.m_null;
				this.m_array = array.m_array;
				this.m_dimensions = array.Dimensions;
				this.m_lengths = array.m_lengths;
				this.m_lowerBounds = array.m_lowerBounds;
				this.Reset();
			}
			public void Reset()
			{
				this.m_current = null;
				this.m_complete = false;
				this.m_indices = (int[])this.m_lowerBounds.Clone();
				this.m_indices[this.m_dimensions - 1]--;
			}
			public bool MoveNext()
			{
				if (this.m_complete)
				{
					return false;
				}
				for (int i = this.m_dimensions - 1; i > -1; i--)
				{
					this.m_indices[i]++;
					if (this.m_indices[i] - this.m_lowerBounds[i] < this.m_lengths[i])
					{
						this.m_current = this.m_array.GetValue(this.m_indices);
						if (this.m_current == null)
						{
							this.m_current = this.m_null;
						}
						return true;
					}
					this.m_indices[i] = this.m_lowerBounds[i];
				}
				this.m_complete = true;
				return false;
			}
		}
		private const int MIN_GROW = 16;
		private System.Type T;
		private bool m_isValueType;
		private bool m_isDynamic;
		private bool m_isMultidims;
		[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
		private System.Array m_array;
		private int m_length = -1;
		private int[] m_lengths;
		private int[] m_lowerBounds;
		private object m_null;
		public SalNumber Length
		{
			get
			{
				if (this.m_length == -1)
				{
					this.m_length = SalArray.CalcArrayLength(this.m_lengths);
				}
				return this.m_length;
			}
		}
		public bool IsDynamic
		{
			get
			{
				return this.m_isDynamic;
			}
		}
		public bool IsMultidimensional
		{
			get
			{
				return this.m_isMultidims;
			}
		}
		public SalNumber Dimensions
		{
			get
			{
				return this.m_lengths.Length;
			}
		}
		public object this[params int[] indices]
		{
			get
			{
				return this.GetValue(indices);
			}
			set
			{
				this.SetValue(value, indices);
			}
		}
		public bool IsEmpty
		{
			get
			{
				return this.Length == 0;
			}
		}
		bool System.Collections.IList.IsFixedSize
		{
			get
			{
				return !this.m_isDynamic;
			}
		}
		bool System.Collections.IList.IsReadOnly
		{
			get
			{
				return false;
			}
		}
		object System.Collections.IList.this[int index]
		{
			get
			{
				return this.GetValue(new int[]
				{
					index
				});
			}
			set
			{
				this.SetValue(value, new int[]
				{
					index
				});
			}
		}
		public bool IsSynchronized
		{
			get
			{
				return this.m_array.IsSynchronized;
			}
		}
		public int Count
		{
			get
			{
				return this.Length;
			}
		}
		public object SyncRoot
		{
			get
			{
				return this;
			}
		}
		[System.Diagnostics.DebuggerStepThrough]
		protected SalArray()
		{
			this.InitArrayType();
			this.FillCreationArguments(null, null);
			this.CreateArray();
		}
		[System.Diagnostics.DebuggerStepThrough]
		protected SalArray(params int[] lengths)
		{
			this.InitArrayType();
			this.FillCreationArguments(lengths, null);
			this.CreateArray();
		}
		[System.Diagnostics.DebuggerStepThrough]
		protected SalArray(params string[] bounds)
		{
			this.InitArrayType();
			this.FillCreationArguments(bounds);
			this.CreateArray();
		}
		[System.Diagnostics.DebuggerStepThrough]
		protected internal SalArray(System.Type T)
		{
			this.InitArrayType(T);
			this.FillCreationArguments(null, null);
			this.CreateArray();
		}
		[System.Diagnostics.DebuggerStepThrough]
		protected internal SalArray(System.Type T, params int[] lengths)
		{
			this.InitArrayType(T);
			this.FillCreationArguments(lengths, null);
			this.CreateArray();
		}
		protected internal SalArray(System.Type T, params string[] bounds)
		{
			this.InitArrayType(T);
			this.FillCreationArguments(bounds);
			this.CreateArray();
		}
		private void InitArrayType()
		{
			this.InitArrayType(base.GetType().DeclaringType);
		}
		private void InitArrayType(System.Type type)
		{
			this.T = type;
			if (this.T == null)
			{
				throw new System.InvalidOperationException(Sys.GetString("InvalidNullArrayType"));
			}
			this.m_isValueType = (this.T.IsValueType || this.T == typeof(SalString));
			this.m_null = this.CreateInstance();
		}
		private void FillCreationArguments(int[] lengths, int[] lowerBounds)
		{
			if (lengths == null)
			{
				this.m_lengths = new int[]
				{
					-1
				};
			}
			else
			{
				this.m_lengths = (int[])lengths.Clone();
			}
			if (lowerBounds == null)
			{
				this.m_lowerBounds = new int[this.m_lengths.Length];
			}
			else
			{
				this.m_lowerBounds = (int[])lowerBounds.Clone();
			}
			this.m_isMultidims = (this.m_lengths.Length > 1);
			if (this.m_lengths[0] == -1)
			{
				this.m_length = -1;
				this.m_lengths[0] = 0;
				this.m_isDynamic = true;
			}
			else
			{
				if (this.m_lengths[0] < -1)
				{
					throw new System.ArgumentOutOfRangeException(Sys.GetString("ArrayElementCannotBeLessThanMinus1"));
				}
			}
			for (int i = 1; i < this.m_lengths.Length; i++)
			{
				if (this.m_lengths[i] < 0)
				{
					throw new System.ArgumentOutOfRangeException(Sys.GetString("ArrayInvalidNumberOfElementsOnly1stDynamic"));
				}
			}
		}
		private void FillCreationArguments(string[] bounds)
		{
			if (bounds == null || bounds.Length == 0)
			{
				this.FillCreationArguments(null, null);
				return;
			}
			int[] array = new int[bounds.Length];
			int[] array2 = new int[bounds.Length];
			for (int i = 0; i < bounds.Length; i++)
			{
				array[i] = this.ParseLength(bounds[i]);
				array2[i] = this.ParseLowerBound(bounds[i]);
				if (array[i] > -1)
				{
					array[i] -= array2[i];
				}
			}
			this.FillCreationArguments(array, array2);
		}
		private int ParseLength(string bound)
		{
			int num = bound.IndexOf(':') + 1;
			bound = bound.Substring(num).Trim();
			if (bound == "*")
			{
				return -1;
			}
			int num2 = int.Parse(bound);
			if (num > 0)
			{
				num2++;
			}
			return num2;
		}
		private int ParseLowerBound(string bound)
		{
			int num = bound.IndexOf(':');
			if (num < 0)
			{
				return 0;
			}
			return int.Parse(bound.Substring(0, num));
		}
		private void CreateArray()
		{
			this.m_array = SalArray.CreateArray(this.T, this.m_lengths, this.m_lowerBounds, this.m_isDynamic);
		}
		private object GetValue(params int[] indices)
		{
			this.ValidateIndex(indices);
			this.EnsureCapacity(indices);
			object obj = this.m_array.GetValue(indices);
			if (obj == null)
			{
				obj = this.CreateInstance();
				this.m_array.SetValue(obj, indices);
			}
			else
			{
				if (!this.m_isValueType && object.ReferenceEquals(obj, this.m_null))
				{
					obj = null;
				}
			}
			return obj;
		}
		private void SetValue(object value, params int[] indices)
		{
			if (value != null && !this.T.IsInstanceOfType(value))
			{
				if (!TypeManager.CanConvertToType(value.GetType(), this.T))
				{
					throw new System.ArgumentException(string.Format(Sys.GetString("ArrayInvalidElementType"), value.GetType().FullName, this.T.FullName));
				}
				value = TypeManager.ConvertToType(value, this.T);
			}
			if (value == null)
			{
				if (this.m_isValueType)
				{
					throw new System.ArgumentException(string.Format(Sys.GetString("ArrayInvalidNullValue"), this.T.FullName));
				}
				value = this.m_null;
			}
			this.ValidateIndex(indices);
			this.EnsureCapacity(indices);
			this.m_array.SetValue(value, indices);
		}
		private void Resize(int length, int lowerBound)
		{
			int[] array = (int[])this.m_lengths.Clone();
			int[] array2 = (int[])this.m_lowerBounds.Clone();
			array[0] = System.Math.Max(0, length);
			array2[0] = System.Math.Max(0, lowerBound);
			System.Array array3 = SalArray.CreateArray(this.T, array, array2, this.m_isDynamic);
			int num = System.Math.Min(this.Length, SalArray.CalcArrayLength(array));
			if (num > 0)
			{
				System.Array.Copy(this.m_array, this.m_lowerBounds[0], array3, lowerBound, num);
			}
			this.m_array = array3;
			this.m_length = -1;
			this.m_lengths = array;
			this.m_lowerBounds = array2;
		}
		private void Resize(int[] lengths, int[] lowerBounds)
		{
			System.Array array = SalArray.CreateArray(this.T, lengths, lowerBounds, this.m_isDynamic);
			int[] array2 = (int[])this.m_lowerBounds.Clone();
			int[] array3 = (int[])lowerBounds.Clone();
			int num = this.Length;
			int num2 = this.Dimensions;
			for (int i = 0; i < num; i++)
			{
				array.SetValue(this.m_array.GetValue(array2), array3);
				for (int j = num2 - 1; j > -1; j--)
				{
					array2[j]++;
					array3[j]++;
					if (array2[j] - this.m_lowerBounds[j] < this.m_lengths[j] && array3[j] - lowerBounds[j] < lengths[j])
					{
						break;
					}
					array2[j] = this.m_lowerBounds[j];
					array3[j] = lowerBounds[j];
				}
			}
			this.m_array = array;
			this.m_length = -1;
			this.m_lengths = (int[])lengths.Clone();
			this.m_lowerBounds = (int[])lowerBounds.Clone();
		}
		private void EnsureCapacity(params int[] indices)
		{
			if (this.m_isDynamic)
			{
				int num = indices[0] - this.m_lowerBounds[0] + 1;
				if (num > this.m_lengths[0])
				{
					bool flag = false;
					try
					{
						System.Threading.Monitor.Enter(this, ref flag);
						if (num > this.m_lengths[0])
						{
							if (indices[0] > this.m_array.GetUpperBound(0))
							{
								this.Resize(num, this.m_lowerBounds[0]);
							}
							else
							{
								this.m_length = -1;
								this.m_lengths[0] = num;
							}
						}
					}
					finally
					{
						if (flag)
						{
							System.Threading.Monitor.Exit(this);
						}
					}
				}
			}
		}
		private void ValidateIndex(params int[] indices)
		{
			int num = System.Math.Min(indices.Length, this.m_lengths.Length);
			for (int i = 0; i < num; i++)
			{
				int num2 = indices[i] - this.m_lowerBounds[i];
				if (num2 < 0)
				{
					throw new System.IndexOutOfRangeException();
				}
				if (num2 > this.m_lengths[i] && !this.m_isDynamic)
				{
					throw new System.IndexOutOfRangeException();
				}
			}
		}
		private static System.Array CreateArray(System.Type T, int[] lengths, int[] lowerBounds, bool dynamic)
		{
			int[] array = (int[])lengths.Clone();
			if (dynamic)
			{
				array[0] = array[0] + System.Math.Max(array[0] / 2, 16);
			}
			if (array.Length == 1)
			{
				array[0] += lowerBounds[0];
				return System.Array.CreateInstance(T, array);
			}
			return System.Array.CreateInstance(T, array, lowerBounds);
		}
		private static int CalcArrayLength(int[] lengths)
		{
			int num = lengths[0];
			if (lengths.Length > 1 && num > 0)
			{
				for (int i = 1; i < lengths.Length; i++)
				{
					num *= lengths[i];
				}
			}
			return num;
		}
		public override string ToString()
		{
			System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
			stringBuilder.Append('{');
			stringBuilder.Append(this.T.FullName);
			stringBuilder.Append('[');
			for (int i = 0; i < this.m_lengths.Length; i++)
			{
				stringBuilder.Append(this.m_lengths[i]);
				if (i < this.m_lengths.Length - 1)
				{
					stringBuilder.Append(',');
				}
			}
			stringBuilder.Append(']');
			stringBuilder.Append('}');
			return stringBuilder.ToString();
		}
		public System.Type GetElementType()
		{
			return this.T;
		}
		public int Add(object value)
		{
			if (this.IsMultidimensional)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotAppendToMultiDim"));
			}
			this.MakeDynamic();
			int count = this.Count;
			this[new int[]
			{
				count
			}] = value;
			return count;
		}
		public void AddRange(System.Collections.ICollection collection)
		{
			if (this.IsMultidimensional)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotAppendToMultiDim"));
			}
			this.MakeDynamic();
			foreach (object current in collection)
			{
				this.Add(current);
			}
		}
		public void Insert(int index)
		{
			if (this.IsMultidimensional)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotInsertToMultiDim"));
			}
			if (index < this.m_lowerBounds[0] || index > this.m_lengths[0] + this.m_lowerBounds[0])
			{
				throw new System.IndexOutOfRangeException();
			}
			this.Resize(this.m_lengths[0] + 1, this.m_lowerBounds[0]);
			if (index < this.m_lengths[0] + this.m_lowerBounds[0] - 1)
			{
				int num = this.m_lengths[0] + this.m_lowerBounds[0] - index - 1;
				if (num > 0)
				{
					System.Array.Copy(this.m_array, index, this.m_array, index + 1, num);
				}
			}
			this.m_array.SetValue(null, index);
		}
		public System.Array GetArray(params int[] capacity)
		{
			if (capacity != null && capacity.Length > 0)
			{
				this.GetValue(capacity);
			}
			return this.m_array;
		}
		public void Remove(int index)
		{
			if (this.IsMultidimensional)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotRemoveFromMultiDim"));
			}
			if (index < this.m_lowerBounds[0] || index >= this.m_lengths[0] + this.m_lowerBounds[0])
			{
				throw new System.IndexOutOfRangeException();
			}
			bool flag = false;
			try
			{
				System.Threading.Monitor.Enter(this, ref flag);
				int num = this.m_lengths[0] + this.m_lowerBounds[0] - 1;
				if (index < num)
				{
					int num2 = num - index;
					if (num2 > 0)
					{
						System.Array.Copy(this.m_array, index + 1, this.m_array, index, num2);
					}
				}
				this.m_length = -1;
				this.m_lengths[0] = this.m_lengths[0] - 1;
				this.m_array.SetValue(null, num);
				int upperBound = this.m_array.GetUpperBound(0);
				if (upperBound - num > System.Math.Max(upperBound / 2, 32))
				{
					this.Resize(this.m_lengths[0], this.m_lowerBounds[0]);
				}
			}
			finally
			{
				if (flag)
				{
					System.Threading.Monitor.Exit(this);
				}
			}
		}
		public int Find(object value)
		{
			if (this.m_isMultidims)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotFindInMultiDim"));
			}
			int result = -1;
			if (!this.IsEmpty)
			{
				int arg_2D_0 = this.m_lengths[0];
				int num = this.m_lowerBounds[0];
				if (this.T == typeof(SalNumber))
				{
					result = SalArray.IndexOf((SalNumber[])this.GetArray(new int[]
					{
						num
					}), value, num, this.Count);
				}
				else
				{
					if (this.T == typeof(SalString))
					{
						result = SalArray.IndexOf((SalString[])this.GetArray(new int[]
						{
							num
						}), value, num, this.Count);
					}
					else
					{
						if (this.T == typeof(SalDateTime))
						{
							result = SalArray.IndexOf((SalDateTime[])this.GetArray(new int[]
							{
								num
							}), value, num, this.Count);
						}
						else
						{
							if (this.T == typeof(SalBoolean))
							{
								result = SalArray.IndexOf((SalBoolean[])this.GetArray(new int[]
								{
									num
								}), value, num, this.Count);
							}
							else
							{
								if (this.T == typeof(SalWindowHandle))
								{
									result = SalArray.IndexOf((SalWindowHandle[])this.GetArray(new int[]
									{
										num
									}), value, num, this.Count);
								}
								else
								{
									
									{
										result = this.IndexOf(value, num, this.Count);
									}
								}
							}
						}
					}
				}
			}
			return result;
		}
		private int IndexOf(object value, int start, int count)
		{
			int num = System.Array.IndexOf(this.m_array, value, start, count);
			if (value == null && !this.m_isValueType)
			{
				int num2 = System.Array.IndexOf(this.m_array, this.m_null, start, count);
				if (num2 > -1)
				{
					num = System.Math.Min(num, num2);
				}
			}
			return num;
		}
		private static int IndexOf(SalNumber[] array, object value, int start, int count)
		{
			if (!(value is SalNumber))
			{
				value = System.Convert.ToDecimal(value);
			}
			SalNumber y = (SalNumber)value;
			for (int i = start; i < count; i++)
			{
				if (SalNumber.Compare(array[i], y) == 0)
				{
					return i;
				}
			}
			return -1;
		}
		private static int IndexOf(SalBoolean[] array, object value, int start, int count)
		{
			if (!(value is SalBoolean))
			{
				value = System.Convert.ToDecimal(value);
			}
			SalBoolean y = (SalBoolean)value;
			for (int i = start; i < count; i++)
			{
				if (SalBoolean.Compare(array[i], y) == 0)
				{
					return i;
				}
			}
			return -1;
		}
		private static int IndexOf(SalString[] array, object value, int start, int count)
		{
			if (!(value is SalString))
			{
				value = (string)value;
			}
			SalString y = (SalString)value;
			for (int i = start; i < count; i++)
			{
				if (SalString.Compare(array[i], y) == 0)
				{
					return i;
				}
			}
			return -1;
		}
		private static int IndexOf(SalDateTime[] array, object item, int start, int count)
		{
			long num = (item is System.DateTime) ? ((System.DateTime)item).Ticks : ((SalDateTime)item).Ticks;
			for (int i = start; i < count; i++)
			{
				if (array[i].Ticks == num)
				{
					return i;
				}
			}
			return -1;
		}
		private static int IndexOf(SalWindowHandle[] array, object value, int start, int count)
		{
			if (value is SalWindowHandle)
			{
				SalWindowHandle handle = (SalWindowHandle)value;
				for (int i = start; i < count; i++)
				{
					if (array[i].CompareTo(handle) == 0)
					{
						return i;
					}
				}
			}
			else
			{
				SalWindowHandle salWindowHandle = (SalWindowHandle)value;
				for (int j = start; j < count; j++)
				{
					if (salWindowHandle.Equals(array[j]))
					{
						return j;
					}
				}
			}
			return -1;
		}
        //private static int IndexOf(SalFileHandle[] array, object value, int start, int count)
        //{
        //    for (int i = start; i < count; i++)
        //    {
        //        if (array[i].Equals(value))
        //        {
        //            return i;
        //        }
        //    }
        //    return -1;
        //}
		public void Sort(int index, int count, System.Collections.IComparer comparer)
		{
			if (this.IsEmpty)
			{
				return;
			}
			if (this.m_isMultidims)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotSortMultiDim"));
			}
			if (index < this.m_lowerBounds[0] || index >= this.m_lengths[0] + this.m_lowerBounds[0])
			{
				throw new System.ArgumentOutOfRangeException(Sys.GetString("ArrayIndex"));
			}
			if (count < 0 || index + count > this.m_lengths[0] + this.m_lowerBounds[0])
			{
				throw new System.ArgumentOutOfRangeException(Sys.GetString("ArrayCount"));
			}
			bool flag = false;
			try
			{
				System.Threading.Monitor.Enter(this, ref flag);
				System.Array.Sort(this.m_array, index, count, comparer);
			}
			finally
			{
				if (flag)
				{
					System.Threading.Monitor.Exit(this);
				}
			}
		}
		protected virtual object CreateInstance()
		{
			return System.Activator.CreateInstance(this.T);
		}
		public void MakeDynamic()
		{
			this.m_isDynamic = true;
		}
		public void Reset()
		{
			if (!this.m_isDynamic)
			{
				throw new System.InvalidOperationException(Sys.GetString("ArrayNotDynamic"));
			}
			this.Resize(0, this.m_lowerBounds[0]);
		}
		public void SetLength(int dim, int length)
		{
			if (dim < 1)
			{
				throw new System.ArgumentOutOfRangeException("dim", dim, Sys.GetString("ArrayInvalidDimension"));
			}
			bool flag = false;
			try
			{
				System.Threading.Monitor.Enter(this, ref flag);
				if (dim == 1)
				{
					if (length != this.m_lengths[0])
					{
						this.Resize(length, this.m_lowerBounds[0]);
					}
				}
				else
				{
					dim--;
					if (length != this.m_lengths[dim])
					{
						int[] array = (int[])this.m_lengths.Clone();
						int[] lowerBounds = (int[])this.m_lowerBounds.Clone();
						array[dim] = length;
						this.Resize(array, lowerBounds);
					}
				}
			}
			finally
			{
				if (flag)
				{
					System.Threading.Monitor.Exit(this);
				}
			}
		}
		public int GetLength(int dim)
		{
			if (dim < 1)
			{
				throw new System.ArgumentOutOfRangeException("dim", dim, Sys.GetString("ArrayInvalidDimension"));
			}
			return this.m_lengths[dim - 1];
		}
		public object ToNativeArray()
		{
			System.Type typeFromHandle;
			if (this.T == typeof(SalNumber))
			{
				typeFromHandle = typeof(decimal);
			}
			else
			{
				if (this.T == typeof(SalString))
				{
					typeFromHandle = typeof(string);
				}
				else
				{
					if (this.T == typeof(SalDateTime))
					{
						typeFromHandle = typeof(System.DateTime);
					}
					else
					{
						if (this.T == typeof(SalBoolean))
						{
							typeFromHandle = typeof(decimal);
						}
						else
						{
							if (!(this.T == typeof(SalWindowHandle)))
							{
								throw new System.NotSupportedException(string.Format(Sys.GetString("ArrayCannotConvertToNative"), this.T.FullName));
							}
							typeFromHandle = typeof(System.IntPtr);
						}
					}
				}
			}
			System.Array array = SalArray.CreateArray(typeFromHandle, this.m_lengths, this.m_lowerBounds, false);
			int num = this.Length;
			int num2 = this.Dimensions;
			int[] array2 = (int[])this.m_lowerBounds.Clone();
			for (int i = 0; i < num; i++)
			{
				array.SetValue(System.Convert.ChangeType(this.m_array.GetValue(array2), typeFromHandle), array2);
				for (int j = num2 - 1; j > -1; j--)
				{
					array2[j]++;
					if (array2[j] - this.m_lowerBounds[j] < this.m_lengths[j])
					{
						break;
					}
					array2[j] = this.m_lowerBounds[j];
				}
			}
			return array;
		}
		public static SalArray FromNativeArray(System.Array array)
		{
			if (array == null)
			{
				return null;
			}
			int[] array2 = new int[array.Rank];
			int[] array3 = new int[array.Rank];
			string[] array4 = new string[array.Rank];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = array.GetLength(i);
				array3[i] = array.GetLowerBound(i);
				if (array3[i] == 0)
				{
					array4[i] = array2[i].ToString();
				}
				else
				{
					array4[i] = array3[i].ToString() + ":" + (array3[i] + array2[i] - 1).ToString();
				}
			}
			System.Type elementType = array.GetType().GetElementType();
			SalArray salArray;
			switch (System.Type.GetTypeCode(elementType))
			{
			case System.TypeCode.Boolean:
			case System.TypeCode.Char:
			case System.TypeCode.SByte:
			case System.TypeCode.Byte:
			case System.TypeCode.Int16:
			case System.TypeCode.UInt16:
			case System.TypeCode.Int32:
			case System.TypeCode.UInt32:
			case System.TypeCode.Int64:
			case System.TypeCode.UInt64:
			case System.TypeCode.Single:
			case System.TypeCode.Double:
			case System.TypeCode.Decimal:
				salArray = new SalArray<SalNumber>(array4);
				goto IL_12A;
			case System.TypeCode.DateTime:
				salArray = new SalArray<SalDateTime>(array4);
				goto IL_12A;
			case System.TypeCode.String:
				salArray = new SalArray<SalString>(array4);
				goto IL_12A;
			}
			throw new System.NotSupportedException(string.Format(Sys.GetString("ArrayCannotCreateOfType"), elementType.FullName));
			IL_12A:
			int num = salArray.Length;
			int num2 = salArray.Dimensions;
			int[] array5 = (int[])array3.Clone();
			for (int j = 0; j < num; j++)
			{
				object value = array.GetValue(array5);
				if (value != null)
				{
					salArray.SetValue(value, array5);
				}
				for (int k = num2 - 1; k > -1; k--)
				{
					array5[k]++;
					if (array5[k] - array3[k] < array2[k])
					{
						break;
					}
					array5[k] = array3[k];
				}
			}
			return salArray;
		}
		public bool Fill(object value, int count)
		{
			if (this.m_isMultidims)
			{
				throw new System.NotSupportedException(Sys.GetString("ArrayCannotFillMultiDim"));
			}
			if (count < 0)
			{
				return true;
			}
			if (count == 0 && !this.m_isDynamic)
			{
				return true;
			}
			int num = count + this.m_lowerBounds[0] - 1;
			this.SetUpperBound(1, num);
			if (count > 0)
			{
				value = TypeManager.ConvertToType(value, this.T);
				for (int i = this.m_lowerBounds[0]; i <= num; i++)
				{
					this.m_array.SetValue(value, i);
				}
			}
			return true;
		}
		public bool SetBounds(int lower, int upper)
		{
			if (!this.IsMultidimensional)
			{
				bool flag = false;
				try
				{
					System.Threading.Monitor.Enter(this, ref flag);
					if (upper == -2147483648)
					{
						this.MakeDynamic();
						bool result = true;
						return result;
					}
					if (upper == -1)
					{
						if (!this.m_isDynamic)
						{
							bool result = false;
							return result;
						}
						if (this.IsEmpty)
						{
							bool result = true;
							return result;
						}
					}
					else
					{
						if (upper < lower)
						{
							bool result = false;
							return result;
						}
					}
					if (lower < 0)
					{
						lower = this.m_lowerBounds[0];
					}
					int num = upper - lower + 1;
					if (lower != this.m_lowerBounds[0] || num != this.m_lengths[0])
					{
						this.Resize(num, lower);
					}
				}
				finally
				{
					if (flag)
					{
						System.Threading.Monitor.Exit(this);
					}
				}
				return true;
			}
			return true;
		}
		public bool SetUpperBound(int dim, int bound)
		{
			if (dim < 1 || dim > this.Dimensions)
			{
				return false;
			}
			bool flag = false;
			bool result;
			try
			{
				System.Threading.Monitor.Enter(this, ref flag);
				if (bound == -2147483648)
				{
					if (dim != 1)
					{
						result = false;
					}
					else
					{
						this.MakeDynamic();
						result = true;
					}
				}
				else
				{
					if (bound == -1)
					{
						if (!this.m_isDynamic)
						{
							result = false;
							return result;
						}
						if (this.IsEmpty)
						{
							result = true;
							return result;
						}
					}
					else
					{
						if (bound < 0)
						{
							result = false;
							return result;
						}
					}
					int length = System.Math.Max(0, bound - this.GetLowerBound(dim) + 1);
					this.SetLength(dim, length);
					result = true;
				}
			}
			finally
			{
				if (flag)
				{
					System.Threading.Monitor.Exit(this);
				}
			}
			return result;
		}
		public bool SetLowerBound(int dim, int bound)
		{
			if (dim < 1 || dim > this.Dimensions)
			{
				return false;
			}
			if (bound < 0)
			{
				return false;
			}
			bool flag = false;
			try
			{
				System.Threading.Monitor.Enter(this, ref flag);
				if (dim == 1)
				{
					if (bound != this.m_lowerBounds[0])
					{
						this.Resize(this.m_lengths[0], bound);
					}
				}
				else
				{
					dim--;
					if (bound != this.m_lowerBounds[dim])
					{
						int[] lengths = (int[])this.m_lengths.Clone();
						int[] array = (int[])this.m_lowerBounds.Clone();
						array[dim] = bound;
						this.Resize(lengths, array);
					}
				}
			}
			finally
			{
				if (flag)
				{
					System.Threading.Monitor.Exit(this);
				}
			}
			return true;
		}
		public SalNumber QueryBounds(ref SalNumber min, ref SalNumber max)
		{
			min = this.GetLowerBound(1);
			max = this.GetUpperBound(1);
			return this.Length;
		}
		public SalNumber GetUpperBound(int dim)
		{
			SalNumber result = 0;
			if (!this.GetUpperBound(dim, ref result))
			{
				return -1;
			}
			return result;
		}
		public bool GetUpperBound(int dim, ref SalNumber ubound)
		{
			if (dim < 1)
			{
				ubound = -1;
				return false;
			}
			if (dim > this.Dimensions)
			{
				return false;
			}
			bool result;
			try
			{
				int num = this.GetLowerBound(dim) + this.GetLength(dim) - 1;
				if (num < 0 && this.m_isDynamic)
				{
					num = 0;
				}
				ubound = num;
				result = true;
			}
			catch (System.IndexOutOfRangeException)
			{
				result = false;
			}
			return result;
		}
		public SalNumber GetLowerBound(int dim)
		{
			SalNumber result = 0;
			if (!this.GetLowerBound(dim, ref result))
			{
				return -1;
			}
			return result;
		}
		public bool GetLowerBound(int dim, ref SalNumber lbound)
		{
			if (dim < 1)
			{
				lbound = -1;
				return false;
			}
			if (dim > this.Dimensions)
			{
				return false;
			}
			bool result;
			try
			{
				dim--;
				lbound = this.m_lowerBounds[dim];
				result = true;
			}
			catch (System.IndexOutOfRangeException)
			{
				result = false;
			}
			return result;
		}
		public SalNumber DimCount()
		{
			return this.Dimensions;
		}
		public bool DimCount(ref SalNumber nDim)
		{
			nDim = this.Dimensions;
			return true;
		}
		public SalNumber Avg()
		{
			if (this.IsEmpty)
			{
				return 0;
			}
			decimal d = 0m;
			int value = this.Length;
			foreach (object current in this)
			{
				if (current != null)
				{
					d += System.Convert.ToDecimal(current);
				}
			}
			return d / value;
		}
		public SalNumber Max()
		{
			if (this.IsEmpty)
			{
				return 0;
			}
			int num = 0;
			decimal num2 = -79228162514264337593543950335m;
			foreach (object current in this)
			{
				if (current != null)
				{
					num++;
					num2 = System.Math.Max(num2, System.Convert.ToDecimal(current));
				}
			}
			if (num == 0)
			{
				num2 = 0m;
			}
			return num2;
		}
		public SalNumber Min()
		{
			if (this.IsEmpty)
			{
				return 0;
			}
			int num = 0;
			decimal num2 = 79228162514264337593543950335m;
			foreach (object current in this)
			{
				if (current != null)
				{
					num++;
					num2 = System.Math.Min(num2, System.Convert.ToDecimal(current));
				}
			}
			if (num == 0)
			{
				num2 = 0m;
			}
			return num2;
		}
		public SalNumber Sum()
		{
			decimal num = 0m;
			foreach (object current in this)
			{
				if (current != null)
				{
					num += System.Convert.ToDecimal(current);
				}
			}
			return num;
		}
		public void Clear()
		{
			this.Reset();
		}
		int System.Collections.IList.Add(object value)
		{
			return this.Add(value);
		}
		bool System.Collections.IList.Contains(object value)
		{
			return this.Find(value) > -1;
		}
		int System.Collections.IList.IndexOf(object value)
		{
			return this.Find(value);
		}
		void System.Collections.IList.Insert(int index, object value)
		{
			this.Insert(index);
			this.SetValue(value, new int[]
			{
				index
			});
		}
		void System.Collections.IList.Remove(object value)
		{
			int num = this.Find(value);
			if (num > -1)
			{
				this.Remove(num);
			}
		}
		void System.Collections.IList.RemoveAt(int index)
		{
			this.Remove(index);
		}
		public void CopyTo(System.Array array, int index)
		{
			System.Array.Copy(this.m_array, this.m_lowerBounds[0], array, index, this.Length);
		}
		public System.Collections.IEnumerator GetEnumerator()
		{
			return new SalArray.Enumerator(this);
		}
	}
	[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")]
	[System.Serializable]
	public class SalArray<T> : SalArray, System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable where T : new()
	{
		private new class Enumerator : SalArray.Enumerator, System.Collections.Generic.IEnumerator<T>, System.IDisposable, System.Collections.IEnumerator
		{
			T System.Collections.Generic.IEnumerator<T>.Current
			{
				get
				{
					return (T)((object)base.Current);
				}
			}
			public Enumerator(SalArray<T> array) : base(array)
			{
			}
			void System.IDisposable.Dispose()
			{
			}
		}
		public new T this[params int[] indices]
		{
			get
			{
				return (T)((object)base[indices]);
			}
			set
			{
				base[indices] = value;
			}
		}
		[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
		private System.Array _array
		{
			get
			{
				return base.GetArray(new int[0]);
			}
		}
		public SalArray() : base(typeof(T))
		{
		}
		public SalArray(params int[] lengths) : base(typeof(T), lengths)
		{
		}
		public SalArray(params string[] bounds) : base(typeof(T), bounds)
		{
		}
		public T[] GetArray(int minLength)
		{
			return (T[])base.GetArray(new int[]
			{
				minLength
			});
		}
		public T[,] GetArray(int minLength1, int minLength2)
		{
			return (T[,])base.GetArray(new int[]
			{
				minLength1,
				minLength2
			});
		}
		public T[,,] GetArray(int minLength1, int minLength2, int minLength3)
		{
			return (T[,,])base.GetArray(new int[]
			{
				minLength1,
				minLength2,
				minLength3
			});
		}
		public T[,,,] GetArray(int minLength1, int minLength2, int minLength3, int minLength4)
		{
			return (T[,,,])base.GetArray(new int[]
			{
				minLength1,
				minLength2,
				minLength3,
				minLength4
			});
		}
		protected override object CreateInstance()
		{
			return (default(T) == null) ? System.Activator.CreateInstance<T>() : default(T);
		}
		System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
		{
			return new SalArray<T>.Enumerator(this);
		}
	}
}
